package com.kaikeba.servlet.handlermapping.impl;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.kaikeba.servlet.adapter.annotation.Controller;
import com.kaikeba.servlet.adapter.annotation.RequestMapping;
import com.kaikeba.servlet.handlermapping.HandlerMapping;
import com.kkb.springframework.beans.aware.BeanFactoryAware;
import com.kkb.springframework.beans.config.BeanDefinition;
import com.kkb.springframework.beans.factory.BeanFactory;

public class RequestMappingHandlerMapping implements HandlerMapping, BeanFactoryAware {

	private BeanFactory beanFactory;
	private Map<String, HandMethod> mapping = new HashMap<String, HandMethod>();

	public void initMethod() {
		try {
			Map<String, BeanDefinition> beans = beanFactory.getBeanDefinitions();
			for (BeanDefinition bean : beans.values()) {
				String beanName = bean.getBeanName();
				String beanClassName = bean.getBeanClassName();
				Class<?> classz = Class.forName(beanClassName);
				if (isHandler(classz)) {
					Object beanObj = beanFactory.getBean(beanName);
					Method[] methods = beanObj.getClass().getDeclaredMethods();
					for (Method method : methods) {
						if (method.isAnnotationPresent(RequestMapping.class)) {
							RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
							HandMethod handMethod = new HandMethod(method, beanObj);
							String uri = requestMapping.value();
							mapping.put(uri, handMethod);
						}
					}
				}
			} 
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private boolean isHandler(Class<?> classz) {
		return classz.isAnnotationPresent(Controller.class) || classz.isAnnotationPresent(RequestMapping.class);
	}

	@Override
	public Object getHandler(HttpServletRequest request) {
		return mapping.get(request.getRequestURI());
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

}
